/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.webservicecomponent.dt.core.rest;

import com.fasterxml.jackson.databind.JsonNode;
import com.inspur.edp.caf.cef.schema.datatype.ObjectType;
import com.inspur.edp.component.schema.GspCompParamType;
import com.inspur.edp.component.schema.enums.GspCompDataType;
import com.inspur.edp.component.schema.resource.RpcResource;
import com.inspur.edp.webservicecomponent.dt.core.vo.CafApiSummary;
import com.inspur.edp.webservicecomponent.metadata.WebServiceComponent;
import com.inspur.edp.webservicecomponent.metadata.WebServiceOperation;
import com.inspur.edp.webservicecomponent.metadata.parameter.WebServiceParameter;
import com.inspur.edp.webservicecomponent.metadata.serializer.WebServiceCmpSerializer;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import io.iec.edp.caf.rpc.api.entity.RpcParamDefinition;
import io.iec.edp.caf.rpc.api.entity.RpcServiceDefinition;
import io.iec.edp.caf.rpc.api.entity.RpcServiceMethodDefinition;
import io.iec.edp.caf.rpc.api.service.InternalServiceManageService;
import org.apache.commons.lang3.StringUtils;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 功能描述:
 *
 * @ClassName: CafApiController
 * @Author: Fynn Qi
 * @Date: 2020/12/30 11:09
 * @Version: V1.0
 */
@Path("/caf")
@Produces({MediaType.APPLICATION_JSON})
@Consumes({MediaType.APPLICATION_JSON})
public class CafApiController {

    private final String SERVICE_ID = "serviceId";

    @Path("/list")
    @GET
    public List<CafApiSummary> getList(@QueryParam("su") String su) {
        InternalServiceManageService svrManager = SpringBeanUtils.getBean(InternalServiceManageService.class);
        String suNoBlankChar = su.trim();
        List<RpcServiceDefinition> serviceList = svrManager.getAllBySU(suNoBlankChar);
        List<CafApiSummary> retList = new ArrayList<>();
        if (serviceList != null) {
            for (RpcServiceDefinition serviceInfo : serviceList) {
                if (retList.stream().anyMatch(x -> x.getId().equals(serviceInfo.getClassName()))) {
                    continue;
                }

                CafApiSummary summaryInfo = new CafApiSummary();
                summaryInfo.setId(serviceInfo.getClassName());
                summaryInfo.setCode(getSimpleClassName(serviceInfo.getClassName()));
                summaryInfo.setName(summaryInfo.getCode());
                summaryInfo.setSu(serviceInfo.getSu());
                summaryInfo.setVersion(serviceInfo.getVersion());
                retList.add(summaryInfo);
            }
        }
        return retList;
    }

    private String getSimpleClassName(String interfaceClass) {
        String simpleClassName = "";
        if (StringUtils.isBlank(interfaceClass)) {
            return simpleClassName;
        }
        int index = interfaceClass.lastIndexOf(".");
        if (index >= 0) {
            simpleClassName = interfaceClass.substring(interfaceClass.lastIndexOf(".") + 1);
        }
        return simpleClassName;
    }

    @Path("/single")
    @GET
    public JsonNode getComponent(@QueryParam("su") String su,
                                 @QueryParam("serviceId") String serviceId) {
        InternalServiceManageService svrManager = SpringBeanUtils.getBean(InternalServiceManageService.class);
        List<RpcServiceDefinition> serviceList = svrManager.getAllBySU(su);
        List<RpcServiceDefinition> queryList = serviceList.stream()
                .filter(x -> x.getClassName().equals(serviceId)).collect(Collectors.toList());
        if (queryList.size() == 0) {
            throw new RuntimeException(String.format("未找到ServiceId：%s的RPC服务。", serviceId));
        }
        RpcServiceDefinition cafApi = queryList.get(0);
        WebServiceComponent component = new WebServiceComponent();

        //sourceInfo初始
        RpcResource sourceInfo = new RpcResource();
        component.setResource(sourceInfo);
        sourceInfo.setApiVersion(cafApi.getVersion());
        sourceInfo.setClassName(cafApi.getClassName());
        sourceInfo.setCommonApi(isCommon(cafApi));
        sourceInfo.setServiceUnit(cafApi.getSu());
        //操作信息
        for (RpcServiceMethodDefinition cafOp : cafApi.getMethods()) {
            WebServiceOperation op = new WebServiceOperation();

            String[] serviceIdSegments = cafOp.getServiceId().split("\\.");
            String serviceName = serviceIdSegments.length > 0 ? serviceIdSegments[serviceIdSegments.length - 1] : null;

            //操作基本信息
            op.setCode(serviceName);
            op.setName(serviceName);
            op.setUri(String.format("%s^^%s", cafOp.getServiceId(), op.getCode()));
            op.setDict(new HashMap<>());
            op.getDict().put(SERVICE_ID, cafOp.getServiceId());
            if (sourceInfo.isCommonApi()) {
                WebServiceParameter parameter = new WebServiceParameter();
                parameter.setCode("serviceUnit");
                parameter.setName("服务单元");
                parameter.setRequired(true);
                GspCompParamType paramType = new GspCompParamType();
                paramType.setType(GspCompDataType.String);
                parameter.setParameterType(paramType);
                parameter.setDescription("公共RPC服务的必带参数，参数位置必须是起始位置");
                op.addParameter(parameter);
            }
            //参数基本信息
            if (cafOp.getParameters() != null) {
                for (RpcParamDefinition cafParam : cafOp.getParameters()) {
                    WebServiceParameter parameter = new WebServiceParameter();
                    parameter.setCode(cafParam.getName());
                    parameter.setName(cafParam.getName());
                    parameter.setRequired(true);
                    parameter.setParameterType(new ObjectType());
                    op.addParameter(parameter);
                }
            }

            //返回值
            if (cafOp.getReturnInfo() != null) {
                op.setReturnType(new ObjectType());
            }
            component.addOperation(op);
        }

        WebServiceCmpSerializer serializer = new WebServiceCmpSerializer();
        return serializer.Serialize(component);
    }

    /**
     * 临时策略，后续需要在设计器上增加一个是否公共RPC的属性设置，让用户确认当前的RPC服务是否是公共的RPC服务
     */
    private boolean isCommon(RpcServiceDefinition cafApi) {
        //SU的编号如果为空，则默认为公共SU
        if (StringUtils.isBlank(cafApi.getSu())) {
            return true;
        } else {
            return cafApi.getSu().toLowerCase().contains("common");
        }
    }

}
